package com.zmn.plat.business.impl.channel;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.zmn.plat.common.constant.ProductConsts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.exception.ZmnException;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.mcc.cas.model.LoginStaff;
import com.zmn.plat.business.interfaces.channel.ChannelBService;
import com.zmn.plat.business.interfaces.channel.ChannelCityPriceRatioBService;
import com.zmn.plat.common.dictionary.BaseCityPriceTypeEnum;
import com.zmn.plat.common.dictionary.BaseCityRatioTypeEnum;
import com.zmn.plat.common.dictionary.ChannelCityRatioTypeEnum;
import com.zmn.plat.common.dictionary.ProductDict;
import com.zmn.plat.common.dto.channel.ChannelCityRatioDIO;
import com.zmn.plat.common.dto.channel.ChannelCityRatioDRO;
import com.zmn.plat.model.entity.area.BaseArea;
import com.zmn.plat.model.entity.base.city.ratio.BaseCityRatio;
import com.zmn.plat.model.entity.channel.ChannelCityPriceRatio;
import com.zmn.plat.model.entity.channel.ChannelCityPriceRatioQuery;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.model.vo.area.ProvinceCityVO;
import com.zmn.plat.model.vo.channel.ChannelCityPriceRatioModifyVo;
import com.zmn.plat.model.vo.channel.ChannelCityRatioBatchVO;
import com.zmn.plat.services.interfaces.area.BaseAreaService;
import com.zmn.plat.services.interfaces.base.city.ratio.BaseCityRatioService;
import com.zmn.plat.services.interfaces.channel.ChannelCityPriceRatioService;
import com.zmn.plat.services.interfaces.product.ServProductService;

/**
 * @author linfeng
 * @since 2019/08/27/15:05
 */
@Service
public class ChannelCityPriceRatioBServiceImpl implements ChannelCityPriceRatioBService {
    private Logger logger = LoggerFactory.getLogger(ChannelCityPriceRatioBServiceImpl.class);

    @Resource
    ChannelCityPriceRatioService channelCityPriceRatioService;

    @Resource
    BaseCityRatioService baseCityRatioService;

    @Resource
    ServProductService servProductService;

    @Resource
    BaseAreaService baseAreaService;

    @Resource
    ChannelBService channelBService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("Duplicates")
    public void addEditCategoryRatio(String mcStaffName, ChannelCityPriceRatioModifyVo cityPriceRatioModify) {
        Date now = DateUtil.getNow();
        Integer channelId = cityPriceRatioModify.getCategOneRatio().getChannelId();
        Integer cityId = cityPriceRatioModify.getCategOneRatio().getCityId();
        Integer bizType = cityPriceRatioModify.getCategOneRatio().getBizType();
        Integer servCategId = cityPriceRatioModify.getCategOneRatio().getServCategId();
        Integer categOneId = cityPriceRatioModify.getCategOneRatio().getCategOneId();
        Integer priceType = cityPriceRatioModify.getCategOneRatio().getPriceType();

        ChannelCityPriceRatioQuery channelCityPriceRatioQuery = new ChannelCityPriceRatioQuery();
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGONERATIO.getCode());
        channelCityPriceRatioQuery.setChannelId(channelId);
        channelCityPriceRatioQuery.setCityId(cityId);
        channelCityPriceRatioQuery.setServCategId(servCategId);
        channelCityPriceRatioQuery.setCategOneId(categOneId);
        channelCityPriceRatioQuery.setPriceType(priceType);
        channelCityPriceRatioQuery.setBizType(bizType);

        ChannelCityPriceRatio categOneRatioResult = channelCityPriceRatioService.findByChannelIdAndCityAndCategAndType(channelCityPriceRatioQuery);
        Double categOneRatio = cityPriceRatioModify.getCategOneRatio().getToBeEffectiveRatio();

        if (categOneRatioResult == null) {
            if (categOneRatio != null) {
                ChannelCityPriceRatio createOneRatio = new ChannelCityPriceRatio();
                createOneRatio = cityPriceRatioModify.getCategOneRatio();
                createOneRatio.setCreater(mcStaffName);
                createOneRatio.setUpdater(mcStaffName);
                createOneRatio.setCreateTime(now);
                createOneRatio.setUpdateTime(now);
                createOneRatio.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGONERATIO.getCode());
                channelCityPriceRatioService.insert(createOneRatio);
            }
        } else {
            if (categOneRatioResult.getRatio() == null && categOneRatio == null) {
                channelCityPriceRatioService.deleteByKey(categOneRatioResult.getRatioId());
            } else {
                categOneRatioResult.setToBeEffectiveRatio(categOneRatio);
                categOneRatioResult.setEffectiveDate(cityPriceRatioModify.getCategOneRatio().getEffectiveDate());
                categOneRatioResult.setUpdateTime(DateUtil.getNow());
                categOneRatioResult.setUpdater(mcStaffName);
                channelCityPriceRatioService.updateByKey(categOneRatioResult);
            }
        }

        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGTWORATIO.getCode());
        List<ChannelCityPriceRatio> dbCategTwoRatios = channelCityPriceRatioService.listByQuery(channelCityPriceRatioQuery);
        List<ChannelCityPriceRatio> categTwoRatios = cityPriceRatioModify.getCategTwoRatioList();
        List<ChannelCityPriceRatio> insertRatioList = new ArrayList<>();
        List<Integer> deleteRatioList = new ArrayList<>();
        List<ChannelCityPriceRatio> updateRatioList = new ArrayList<>();
        if (categTwoRatios != null && categTwoRatios.size() > 0) {
            categTwoRatios.forEach(e -> {
                channelCityPriceRatioQuery.setCategId(e.getCategId());
                ChannelCityPriceRatio dbRatio = findChannelCityRatioByQueryOfCategTwoRatioList(channelCityPriceRatioQuery, dbCategTwoRatios);

                if (dbRatio == null) {
                    if (e.getToBeEffectiveRatio() != null) {
                        e.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGTWORATIO.getCode());
                        e.setCreater(mcStaffName);
                        e.setUpdater(mcStaffName);
                        e.setCreateTime(now);
                        e.setUpdateTime(now);
                        insertRatioList.add(e);
                    }
                } else {
                    if (dbRatio.getRatio() == null && e.getToBeEffectiveRatio() == null) {
                        deleteRatioList.add(dbRatio.getRatioId());
                    } else {
                        e.setUpdateTime(DateUtil.getNow());
                        e.setUpdater(mcStaffName);
                        e.setRatioId(dbRatio.getRatioId());
                        updateRatioList.add(e);
                    }
                }
            });

            if (CollectionUtil.isNotNullOrEmpty(insertRatioList)) {
                channelCityPriceRatioService.insertBatch(insertRatioList);
            }
            if (CollectionUtil.isNotNullOrEmpty(deleteRatioList)) {
                channelCityPriceRatioService.deleteByKeys(deleteRatioList);
            }
            if (CollectionUtil.isNotNullOrEmpty(updateRatioList)) {
                channelCityPriceRatioService.updateToBeEffectiveRatioBatch(updateRatioList);
            }
        }

    }

    @Override
    @Cacheable(cacheNames = "redis1h", key = "'base:ratio:channel:'+#p0+':city:'+#p1+':product:'+#p2+':type:'+#p3+':priceType:'+#p4", unless = "#result == null")
    public Float findRatioByChannelIdAndCityId(Integer channelId, Integer cityId, Integer productId, Integer type, Integer priceType) {
        ServProduct servProduct = servProductService.findByKeyWithCache(productId);
        if (servProduct == null) {
            throw new ZmnException("产品不存在!id:" + productId);
        }
        // 查询二级分类渠道城市系数
        ChannelCityPriceRatioQuery channelCityPriceRatioQuery = new ChannelCityPriceRatioQuery();
        channelCityPriceRatioQuery.setChannelId(channelId);
        channelCityPriceRatioQuery.setCityId(cityId);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGTWORATIO.getCode());
        channelCityPriceRatioQuery.setServCategId(servProduct.getServCategId());
        channelCityPriceRatioQuery.setCategOneId(servProduct.getCategOneId());
        channelCityPriceRatioQuery.setCategId(servProduct.getCategId());
        channelCityPriceRatioQuery.setBizType(type);
        channelCityPriceRatioQuery.setPriceType(priceType);
        ChannelCityPriceRatio channelCityPriceRatio = channelCityPriceRatioService.findByChannelIdAndCityAndCategAndType(channelCityPriceRatioQuery);
        if (!Objects.isNull(channelCityPriceRatio) && !Objects.isNull(channelCityPriceRatio.getRatio())) {
            return Float.parseFloat(channelCityPriceRatio.getRatio().toString());
        }

        // 查询一级分类渠道城市系数
        channelCityPriceRatioQuery.setCategId(null);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGONERATIO.getCode());
        channelCityPriceRatio = channelCityPriceRatioService.findByChannelIdAndCityAndCategAndType(channelCityPriceRatioQuery);
        if (!Objects.isNull(channelCityPriceRatio) && !Objects.isNull(channelCityPriceRatio.getRatio())) {
            return Float.parseFloat(channelCityPriceRatio.getRatio().toString());
        }

        // 查询渠道城市系数
        channelCityPriceRatioQuery.setServCategId(null);
        channelCityPriceRatioQuery.setCategOneId(null);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYRATIO.getCode());
        channelCityPriceRatio = channelCityPriceRatioService.findByChannelIdAndCityAndCategAndType(channelCityPriceRatioQuery);
        if (!Objects.isNull(channelCityPriceRatio) && !Objects.isNull(channelCityPriceRatio.getRatio())) {
            return Float.parseFloat(channelCityPriceRatio.getRatio().toString());
        }

        // 查询渠道默认系数
        channelCityPriceRatioQuery.setCityId(null);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELRATIO.getCode());
        channelCityPriceRatio = channelCityPriceRatioService.findByChannelIdAndCityAndCategAndType(channelCityPriceRatioQuery);
        if (!Objects.isNull(channelCityPriceRatio) && !Objects.isNull(channelCityPriceRatio.getRatio())) {
            return Float.parseFloat(channelCityPriceRatio.getRatio().toString());
        }

        // 查询二级分类基础城市系数
        BaseCityRatio baseCityPriceRatio = baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType, BaseCityRatioTypeEnum.CITYCATEGTWORATIO.getCode(), cityId,
            servProduct.getServCategId(), servProduct.getCategOneId(), servProduct.getCategId(), type);
        if (!Objects.isNull(baseCityPriceRatio) && !Objects.isNull(baseCityPriceRatio.getRatio())) {
            return Float.parseFloat(baseCityPriceRatio.getRatio().toString());
        }

        // 查询一级分类基础城市系数
        baseCityPriceRatio = baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType, BaseCityRatioTypeEnum.CITYCATEGONERATIO.getCode(), cityId, servProduct.getServCategId(),
            servProduct.getCategOneId(), null, type);
        if (!Objects.isNull(baseCityPriceRatio) && !Objects.isNull(baseCityPriceRatio.getRatio())) {
            return Float.parseFloat(baseCityPriceRatio.getRatio().toString());
        }

        // 查询基础城市系数
        baseCityPriceRatio = baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType, BaseCityRatioTypeEnum.CITYRATIO.getCode(), cityId, null, null, null, type);
        if (!Objects.isNull(baseCityPriceRatio) && !Objects.isNull(baseCityPriceRatio.getRatio())) {
            return Float.parseFloat(baseCityPriceRatio.getRatio().toString());
        }
        return null;
    }

    @Override
    public ChannelCityRatioDRO getRatioByChannelIdAndCityIdAndProductIdAndBizType(ChannelCityRatioDIO channelCityRatioDIO) {
        ServProduct servProduct = servProductService.findByKeyWithCache(channelCityRatioDIO.getProductId());
        if (servProduct == null) {
            return null;
        }
        BeanCopier copier = BeanCopier.create(ChannelCityRatioDIO.class, ChannelCityRatioDRO.class, false);
        ChannelCityRatioDRO dro = new ChannelCityRatioDRO();
        copier.copy(channelCityRatioDIO, dro, null);
        Float ratio = findRatioByChannelIdAndCityId(channelCityRatioDIO.getChannelId(), channelCityRatioDIO.getCityId(), channelCityRatioDIO.getProductId(), channelCityRatioDIO.getType(),
            BaseCityPriceTypeEnum.PRICE.getCode());
        dro.setRatio(ratio == null ? GlobalConsts.NO : ratio);
        dro.setCategOneId(servProduct.getCategOneId());
        dro.setServCategId(servProduct.getServCategId());
        dro.setCategTwoId(servProduct.getCategId());
        return dro;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("Duplicates")
    public void saveCityRatioBatch(LoginStaff mcStaff, ChannelCityRatioBatchVO cityRatioBatchVO) {
        List<ProvinceCityVO> provinceCityVOS = cityRatioBatchVO.getProvinceCityVOS();
        Integer bizType = cityRatioBatchVO.getBizType();
        Integer priceType = cityRatioBatchVO.getPriceType();

        List<Integer> cityIdList = provinceCityVOS.stream().map(ProvinceCityVO::getCityId).collect(Collectors.toList());
        ChannelCityPriceRatioQuery channelCityPriceRatioQuery = new ChannelCityPriceRatioQuery();
        channelCityPriceRatioQuery.setChannelId(cityRatioBatchVO.getChannelId());
        channelCityPriceRatioQuery.setCityIds(cityIdList);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYRATIO.getCode());
        channelCityPriceRatioQuery.setBizType(bizType);
        channelCityPriceRatioQuery.setPriceType(cityRatioBatchVO.getPriceType());
        List<ChannelCityPriceRatio> channelCityPriceRatios = channelCityPriceRatioService.listByQuery(channelCityPriceRatioQuery);
        Map<Integer, ChannelCityPriceRatio> map = channelCityPriceRatios.stream().collect(Collectors.toMap(o -> o.getCityId(), o -> o));
        Map<Integer, ChannelCityPriceRatio> mapM = new HashMap<>();
        if(bizType== ProductConsts.BIZ_TYPE_C){
            //C类业务价格系数新增修改计价器3.0默认系数
            channelCityPriceRatioQuery.setBizType(null);
            channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYMETER3RATIO.getCode());
            List<ChannelCityPriceRatio> channelCityPriceRatioMList = channelCityPriceRatioService.listByQuery(channelCityPriceRatioQuery);
            mapM = channelCityPriceRatioMList.stream().collect(Collectors.toMap(ChannelCityPriceRatio::getCityId, o -> o));
        }


        List<ChannelCityPriceRatio> updateRatioList = new ArrayList<>();
        List<ChannelCityPriceRatio> insertRatioList = new ArrayList<>();
        // 需要删除的系数集合
        List<Integer> deleteRatioList = new ArrayList<>();

        Double toBeEffectiveRatio = cityRatioBatchVO.getToBeEffectiveRatio();
        Double meterToBeEffectiveRatio = cityRatioBatchVO.getMeterToBeEffectiveRatio();
        Date effectiveDate = cityRatioBatchVO.getEffectiveDate();

        for (int i = 0; i < provinceCityVOS.size(); i++) {
            ProvinceCityVO provinceCityVO = provinceCityVOS.get(i);
            if(bizType== ProductConsts.BIZ_TYPE_C){
                //C类业务价格系数新增修改计价器3.0默认系数
                ChannelCityPriceRatio innerRatioM = mapM.get(provinceCityVO.getCityId());
                if (Objects.isNull(innerRatioM)) {
                    if (meterToBeEffectiveRatio != null) {
                        ChannelCityPriceRatio channelCityPriceRatio = new ChannelCityPriceRatio();
                        channelCityPriceRatio.setChannelId(cityRatioBatchVO.getChannelId());
                        channelCityPriceRatio.setToBeEffectiveRatio(meterToBeEffectiveRatio);
                        channelCityPriceRatio.setEffectiveDate(effectiveDate);
                        channelCityPriceRatio.setProvinceId(provinceCityVO.getProvinceId());
                        channelCityPriceRatio.setCityId(provinceCityVO.getCityId());
                        channelCityPriceRatio.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYMETER3RATIO.getCode());
                        channelCityPriceRatio.setBizType(null);
                        channelCityPriceRatio.setPriceType(priceType);
                        channelCityPriceRatio.setUpdater(mcStaff.getRealName());
                        channelCityPriceRatio.setUpdateTime(DateUtil.getNow());
                        channelCityPriceRatio.setCreater(mcStaff.getRealName());
                        channelCityPriceRatio.setCreateTime(DateUtil.getNow());
                        insertRatioList.add(channelCityPriceRatio);
                    }
                } else {
                    if (innerRatioM.getRatio() == null && meterToBeEffectiveRatio == null) {
                        deleteRatioList.add(innerRatioM.getRatioId());
                    } else {
                        innerRatioM.setUpdateTime(DateUtil.getNow());
                        innerRatioM.setUpdater(mcStaff.getRealName());
                        innerRatioM.setToBeEffectiveRatio(meterToBeEffectiveRatio);
                        innerRatioM.setEffectiveDate(effectiveDate);
                        updateRatioList.add(innerRatioM);
                    }
                }
            }
            ChannelCityPriceRatio innerRatio = map.get(provinceCityVO.getCityId());

            if (Objects.isNull(innerRatio)) {
                if (toBeEffectiveRatio != null) {
                    ChannelCityPriceRatio channelCityPriceRatio = new ChannelCityPriceRatio();
                    channelCityPriceRatio.setChannelId(cityRatioBatchVO.getChannelId());
                    channelCityPriceRatio.setToBeEffectiveRatio(toBeEffectiveRatio);
                    channelCityPriceRatio.setEffectiveDate(effectiveDate);
                    channelCityPriceRatio.setProvinceId(provinceCityVO.getProvinceId());
                    channelCityPriceRatio.setCityId(provinceCityVO.getCityId());
                    channelCityPriceRatio.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYRATIO.getCode());
                    channelCityPriceRatio.setBizType(bizType);
                    channelCityPriceRatio.setPriceType(priceType);
                    channelCityPriceRatio.setUpdater(mcStaff.getRealName());
                    channelCityPriceRatio.setUpdateTime(DateUtil.getNow());
                    channelCityPriceRatio.setCreater(mcStaff.getRealName());
                    channelCityPriceRatio.setCreateTime(DateUtil.getNow());
                    insertRatioList.add(channelCityPriceRatio);
                }
            } else {
                if (innerRatio.getRatio() == null && toBeEffectiveRatio == null) {
                    deleteRatioList.add(innerRatio.getRatioId());
                } else {
                    innerRatio.setUpdateTime(DateUtil.getNow());
                    innerRatio.setUpdater(mcStaff.getRealName());
                    innerRatio.setToBeEffectiveRatio(toBeEffectiveRatio);
                    innerRatio.setEffectiveDate(effectiveDate);
                    updateRatioList.add(innerRatio);
                }
            }
        }

        if (CollectionUtil.isNotNullOrEmpty(insertRatioList)) {
            channelCityPriceRatioService.insertBatch(insertRatioList);
        }
        if (CollectionUtil.isNotNullOrEmpty(deleteRatioList)) {
            channelCityPriceRatioService.deleteByKeys(deleteRatioList);
        }
        if (CollectionUtil.isNotNullOrEmpty(updateRatioList)) {
            channelCityPriceRatioService.updateToBeEffectiveRatioBatch(updateRatioList);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("Duplicates")
    public void saveCityCategRatioBatch(LoginStaff mcStaff, ChannelCityRatioBatchVO cityRatioBatchVO) {
        List<Integer> cityIdList = StringUtil.convertStrsToList(cityRatioBatchVO.getCityIdStr());

        Map<Integer, Integer> cityProvMap = new HashMap<>(cityIdList.size());
        if (CollectionUtil.isNotNullOrEmpty(cityIdList)) {
            List<BaseArea> cityList = baseAreaService.findByKeys(cityIdList);
            cityProvMap = cityList.stream().collect(Collectors.toMap(BaseArea::getAreaId, BaseArea::getParentId));
        }

        // 处理一级分类系数
        ChannelCityPriceRatioQuery channelCityPriceRatioQuery = new ChannelCityPriceRatioQuery();
        channelCityPriceRatioQuery.setChannelId(cityRatioBatchVO.getChannelId());
        channelCityPriceRatioQuery.setCityIds(cityIdList);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGONERATIO.getCode());
        channelCityPriceRatioQuery.setServCategId(cityRatioBatchVO.getServCategId());
        channelCityPriceRatioQuery.setCategOneId(cityRatioBatchVO.getCategOneId());
        channelCityPriceRatioQuery.setBizType(cityRatioBatchVO.getBizType());
        channelCityPriceRatioQuery.setPriceType(cityRatioBatchVO.getPriceType());
        List<ChannelCityPriceRatio> channelCityPriceRatios = channelCityPriceRatioService.listByQuery(channelCityPriceRatioQuery);

        List<ChannelCityPriceRatio> updateRatioList = new ArrayList<>();
        List<ChannelCityPriceRatio> insertRatioList = new ArrayList<>();
        // 需要删除的系数集合
        List<Integer> deleteRatioList = new ArrayList<>();

        for (int i = 0; i < cityIdList.size(); i++) {
            Integer cityId = cityIdList.get(i);
            channelCityPriceRatioQuery.setCityId(cityId);
            ChannelCityPriceRatio innerRatio = this.findChannelCityRatioByQueryOfCategOneRatioList(channelCityPriceRatioQuery, channelCityPriceRatios);
            Double toBeEffectiveRatio = cityRatioBatchVO.getCategOneRatio().getToBeEffectiveRatio();
            Date effectiveDate = cityRatioBatchVO.getCategOneRatio().getEffectiveDate();
            if (Objects.isNull(innerRatio)) {
                if (toBeEffectiveRatio != null) {
                    ChannelCityPriceRatio channelCityPriceRatio = new ChannelCityPriceRatio();
                    BeanUtils.copyProperties(cityRatioBatchVO.getCategOneRatio(), channelCityPriceRatio);
                    channelCityPriceRatio.setProvinceId(cityProvMap.get(cityId));
                    channelCityPriceRatio.setCityId(cityId);
                    channelCityPriceRatio.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGONERATIO.getCode());
                    channelCityPriceRatio.setUpdater(mcStaff.getRealName());
                    channelCityPriceRatio.setUpdateTime(DateUtil.getNow());
                    channelCityPriceRatio.setCreater(mcStaff.getRealName());
                    channelCityPriceRatio.setCreateTime(DateUtil.getNow());
                    insertRatioList.add(channelCityPriceRatio);
                }
            } else {
                if (innerRatio.getRatio() == null && toBeEffectiveRatio == null) {
                    deleteRatioList.add(innerRatio.getRatioId());
                } else {
                    innerRatio.setUpdateTime(DateUtil.getNow());
                    innerRatio.setUpdater(mcStaff.getRealName());
                    innerRatio.setToBeEffectiveRatio(toBeEffectiveRatio);
                    innerRatio.setEffectiveDate(effectiveDate);
                    updateRatioList.add(innerRatio);
                }
            }
        }

        // 处理二级分类系数
        List<ChannelCityPriceRatio> categTwoRatioList = cityRatioBatchVO.getChannelCityPriceRatioList();
        List<Integer> categTwoIdList = categTwoRatioList.stream().map(e -> e.getCategId()).collect(Collectors.toList());
        channelCityPriceRatioQuery.setCategIds(categTwoIdList);
        channelCityPriceRatioQuery.setCityId(null);
        channelCityPriceRatioQuery.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGTWORATIO.getCode());
        List<ChannelCityPriceRatio> dbCategTwoRatios = channelCityPriceRatioService.listByQuery(channelCityPriceRatioQuery);

        for (int i = 0; i < cityIdList.size(); i++) {
            Integer cityId = cityIdList.get(i);
            for (ChannelCityPriceRatio categTwoRatio : cityRatioBatchVO.getChannelCityPriceRatioList()) {
                channelCityPriceRatioQuery.setCityId(cityId);
                channelCityPriceRatioQuery.setCategId(categTwoRatio.getCategId());
                ChannelCityPriceRatio dbRatio = this.findChannelCityRatioByQueryOfCategTwoRatioList(channelCityPriceRatioQuery, dbCategTwoRatios);

                if (dbRatio == null) {
                    if (categTwoRatio.getToBeEffectiveRatio() != null) {
                        ChannelCityPriceRatio insertRatio = new ChannelCityPriceRatio();
                        BeanUtils.copyProperties(categTwoRatio, insertRatio);
                        insertRatio.setCityId(cityId);
                        insertRatio.setProvinceId(cityProvMap.get(cityId));
                        insertRatio.setRatioType(ChannelCityRatioTypeEnum.CHANNELCITYCATEGTWORATIO.getCode());
                        insertRatio.setCreater(mcStaff.getRealName());
                        insertRatio.setUpdater(mcStaff.getRealName());
                        insertRatio.setCreateTime(DateUtil.getNow());
                        insertRatio.setUpdateTime(DateUtil.getNow());
                        insertRatioList.add(insertRatio);
                    }
                } else {
                    if (dbRatio.getRatio() == null && categTwoRatio.getToBeEffectiveRatio() == null) {
                        deleteRatioList.add(dbRatio.getRatioId());
                    } else {
                        dbRatio.setUpdateTime(DateUtil.getNow());
                        dbRatio.setUpdater(mcStaff.getRealName());
                        dbRatio.setToBeEffectiveRatio(categTwoRatio.getToBeEffectiveRatio());
                        dbRatio.setEffectiveDate(categTwoRatio.getEffectiveDate());
                        updateRatioList.add(dbRatio);
                    }
                }
            }
        }

        if (CollectionUtil.isNotNullOrEmpty(insertRatioList)) {
            channelCityPriceRatioService.insertBatch(insertRatioList);
        }
        if (CollectionUtil.isNotNullOrEmpty(deleteRatioList)) {
            channelCityPriceRatioService.deleteByKeys(deleteRatioList);
        }
        if (CollectionUtil.isNotNullOrEmpty(updateRatioList)) {
            channelCityPriceRatioService.updateToBeEffectiveRatioBatch(updateRatioList);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyRatio(Integer sourceChannelId, Integer targetChannelId, Integer bizType, Integer priceType, Date effectiveDate, List<Integer> ratioTypes, String opertor) {
        channelCityPriceRatioService.deleteByChannelIdAndPriceTypeAndBizTypeAndRatioTypes(targetChannelId, priceType, bizType, ratioTypes);
        channelCityPriceRatioService.copyRatio(sourceChannelId, targetChannelId, bizType, priceType, effectiveDate, ratioTypes, opertor);
        channelBService.createLog(targetChannelId, null, ProductDict.getBizTypeCNENName(bizType), null);
    }

    private ChannelCityPriceRatio findChannelCityRatioByQueryOfCategOneRatioList(ChannelCityPriceRatioQuery cityCategRatioQuery, List<ChannelCityPriceRatio> categOneRatioList) {
        ChannelCityPriceRatio channelCityPriceRatio;
        for (int i = 0; i < categOneRatioList.size(); i++) {
            channelCityPriceRatio = categOneRatioList.get(i);
            if (Objects.equals(cityCategRatioQuery.getCityId(), channelCityPriceRatio.getCityId()) && Objects.equals(cityCategRatioQuery.getServCategId(), channelCityPriceRatio.getServCategId())
                && Objects.equals(cityCategRatioQuery.getCategOneId(), channelCityPriceRatio.getCategOneId()) && Objects.equals(cityCategRatioQuery.getBizType(), channelCityPriceRatio.getBizType())
                && Objects.equals(cityCategRatioQuery.getPriceType(), channelCityPriceRatio.getPriceType()) && Objects.equals(cityCategRatioQuery.getRatioType(), channelCityPriceRatio.getRatioType())
                && Objects.equals(cityCategRatioQuery.getChannelId(), channelCityPriceRatio.getChannelId())) {
                return channelCityPriceRatio;
            }
        }
        return null;
    }

    private ChannelCityPriceRatio findChannelCityRatioByQueryOfCategTwoRatioList(ChannelCityPriceRatioQuery cityCategRatioQuery, List<ChannelCityPriceRatio> categTwoRatioList) {
        ChannelCityPriceRatio channelCityPriceRatio;
        for (int i = 0; i < categTwoRatioList.size(); i++) {
            channelCityPriceRatio = categTwoRatioList.get(i);
            if (Objects.equals(cityCategRatioQuery.getCityId(), channelCityPriceRatio.getCityId()) && Objects.equals(cityCategRatioQuery.getServCategId(), channelCityPriceRatio.getServCategId())
                && Objects.equals(cityCategRatioQuery.getCategOneId(), channelCityPriceRatio.getCategOneId()) && Objects.equals(cityCategRatioQuery.getCategId(), channelCityPriceRatio.getCategId())
                && Objects.equals(cityCategRatioQuery.getBizType(), channelCityPriceRatio.getBizType()) && Objects.equals(cityCategRatioQuery.getPriceType(), channelCityPriceRatio.getPriceType())
                && Objects.equals(cityCategRatioQuery.getRatioType(), channelCityPriceRatio.getRatioType())
                && Objects.equals(cityCategRatioQuery.getChannelId(), channelCityPriceRatio.getChannelId())) {
                return channelCityPriceRatio;
            }
        }
        return null;
    }
}
